package com.syni.mdd.yhd.common.all.quartz.activity;

import com.syni.mdd.yhd.common.all.constants.Constants;
import com.syni.mdd.yhd.common.all.entity.BmsBusiness;
import com.syni.mdd.yhd.common.all.entity.BmsDxClientRole;
import com.syni.mdd.yhd.common.all.entity.BmsDxOrder;
import com.syni.mdd.yhd.common.all.entity.activity.CountBussinessActivity;
import com.syni.mdd.yhd.common.all.entity.activity.CountUserActivity;
import com.syni.mdd.yhd.common.all.entity.coupon.BmsUserReceCoupon;
import com.syni.mdd.yhd.common.all.entity.user.BmsUser;
import com.syni.mdd.yhd.common.all.service.*;
import com.syni.mdd.yhd.common.all.service.record.CountBussinessActivityService;
import com.syni.mdd.yhd.common.all.service.record.CountUserActivityService;
import com.syni.mdd.yhd.common.all.utils.SpecificationUtils;
import com.syni.mdd.sjb.common.component.utils.common.utils.ArithUtil;
import com.syni.mdd.sjb.common.component.utils.common.utils.DateTimeUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @className BmsVideoQuartz
 * @description TOO
 * @Author cfx
 * @DATE 2019/7/26 16:15
 * @VERSION 1.0
 **/
@Component
@EnableScheduling
public class BussinessActivityQuartz {
    private final Logger log = LoggerFactory.getLogger(getClass());

    @Autowired
    CountBussinessActivityService countBussinessActivityService;

    @Autowired
    CountUserActivityService countUserActivityService;

    @Autowired
    BmsUserReceCouponService bmsUserReceCouponService;

    @Autowired
    BmsBusinessService bmsBusinessService;

    @Autowired
    BmsUserService bmsUserService;

    @Autowired
    BmsDxClientRoleService bmsDxClientRoleService;

    @Autowired
    BmsDxOrderService bmsDxOrderService;

    //@Scheduled(cron = "0 0 0/6 * * ?")  //每6小时统计一次
    //@Scheduled(cron = "0/5 * * * * ?")
    @Scheduled(cron = "0 0 0 * * ?")  //每天晚上凌晨执行一次定时任务
    public void countBusinessActivityQuartz() {
        Date nowTime = new Date();
        Date startTime = DateTimeUtils.getStartTimeOfDay(DateTimeUtils.addDay(nowTime,-1));
        //System.out.println("开始时间：" + startTime.getTime());
        //Date startTime = new Date(0);

        Date endTime = DateTimeUtils.getEndTimeOfDay(startTime);
        //Date endTime = nowTime;
        System.out.println("结束时间：" + nowTime.getTime());

        //Date startTime = new Date(0);
        System.out.println("开始时间：" + startTime.getTime());
        //统计这个时间段用户收到的所有券（商户端）
        countBusinessToSendStamps(startTime,endTime);
        //查询这个时间段用户使用的券（商户端）
        countBusinessUserUse(startTime,endTime);
        //用户端
        countUserActivity(startTime,endTime);
    }

    public void countUserActivity(Date startTime, Date nowTime) {
        Map<String,Object> condtionMap = new HashMap<>();
        condtionMap.put("newTime_GTTE",startTime);
        condtionMap.put("newTime_LTT",nowTime);
        condtionMap.put("type",Constants.ACTIVITY_PRODUCE);
        Map<Integer,BmsUserReceCoupon> bmsUserReceCouponMap = new HashMap<>();
        List<BmsUserReceCoupon> bmsUserReceCoupons = bmsUserReceCouponService.getBaseDao().findAll(new SpecificationUtils(condtionMap));
        if(bmsUserReceCoupons != null && bmsUserReceCoupons.size() > 0){
            Set<Integer> userIds = bmsUserReceCoupons.stream().map(BmsUserReceCoupon::getUserId).collect(Collectors.toSet());
            Set<Integer> businessIds = bmsUserReceCoupons.stream().map(BmsUserReceCoupon::getBusinessId).collect(Collectors.toSet());
            Map<Integer, BmsUser> userMap = bmsUserService.getUserByIds(userIds);
            Map<Integer, BmsDxClientRole> bmsDxClientRoleMap = bmsDxClientRoleService.getUserClienRole(userIds,Constants.GENERAL_USER_ROLE_ID);
            Map<Integer, BmsBusiness> bmsBusinessMap = bmsBusinessService.findBusinessByIds(businessIds);
            List<CountUserActivity> countUserActivities = new LinkedList<>();
            for(BmsUserReceCoupon bmsUserReceCoupon : bmsUserReceCoupons){
                CountUserActivity countUserActivity = new CountUserActivity();
                if(bmsDxClientRoleMap.containsKey(bmsUserReceCoupon.getUserId())) {
                    countUserActivity.setRegisterTime(bmsDxClientRoleMap.get(bmsUserReceCoupon.getUserId()).getNewTime());
                }
                if(userMap.containsKey(bmsUserReceCoupon.getUserId())) {
                    BmsUser bmsUser = userMap.get(bmsUserReceCoupon.getUserId());
                    countUserActivity.setRegisterUser(bmsUser.getId());
                    countUserActivity.setRegisterPhone(bmsUser.getPhone());
                }
                countUserActivity.setReceiveId(bmsUserReceCoupon.getFullCouponId());
                if(bmsBusinessMap.containsKey(bmsUserReceCoupon.getBusinessId())) {
                    String[] fullRule = bmsUserReceCoupon.getBmsFullCoupon().getFullRule().split("_");
                    countUserActivity.setReceiveName(String.format("%s - 满%s减%s", bmsBusinessMap.get(bmsUserReceCoupon.getBusinessId()).getVendorName(),fullRule[0],fullRule[1]));
                }
                countUserActivity.setIsUse("否");
                if(bmsUserReceCoupon.getStatus() == Constants.COMMON_FLAG_TRUE_INT){
                    countUserActivity.setIsUse("是");
                    countUserActivity.setUseTime(bmsUserReceCoupon.getUseTime());
                    BmsDxOrder bmsDxOrder = this.searchFullCouponOrder(bmsUserReceCoupon.getId());
                    if(bmsDxOrder != null){
                        countUserActivity.setDealAmount(bmsDxOrder.getActualConsum());
                    }
                }
                countUserActivity.setNewTime(new Date());
                countUserActivities.add(countUserActivity);
            }
            if(countUserActivities.size() > 0){
                countUserActivityService.getBaseDao().saveAll(countUserActivities);
            }
        }
    }

    private BmsDxOrder searchFullCouponOrder(Integer id) {
        Map<String,Object> conditionMap = new HashMap<>();
        conditionMap.put("fullCouponId",id);
        List<BmsDxOrder> bmsDxOrders = bmsDxOrderService.getBaseDao().findAll(new SpecificationUtils(conditionMap));
        if(bmsDxOrders != null && bmsDxOrders.size() > 0){
            return bmsDxOrders.get(0);
        }
        return null;

    }

    /**
     * @Description 查询这个时间段用户使用的券
     * @Author: cfx
     * @Date: 2019/10/1
     */
    public void countBusinessUserUse(Date startTime, Date nowTime) {
        Map<String,Object> condtionMap = new HashMap<>();
        condtionMap.put("useTime_GTTE",startTime);
        condtionMap.put("useTime_LTT",nowTime);
        condtionMap.put("status",Constants.COMMON_FLAG_TRUE_INT);
        List<BmsUserReceCoupon> bmsUserReceCoupons = bmsUserReceCouponService.getBaseDao().findAll(new SpecificationUtils(condtionMap));
        if(bmsUserReceCoupons != null && bmsUserReceCoupons.size() > 0) {
            Map<Integer,Integer> countMap = new HashMap<>();
            for(BmsUserReceCoupon bmsUserReceCoupon : bmsUserReceCoupons){
                if(!countMap.containsKey(bmsUserReceCoupon.getBusinessId())){
                    countMap.put(bmsUserReceCoupon.getBusinessId(),0);
                }
                countMap.put(bmsUserReceCoupon.getBusinessId(),countMap.get(bmsUserReceCoupon.getBusinessId()) + 1);
            }
            Set<Integer> userReceIds = bmsUserReceCoupons.stream().map(BmsUserReceCoupon::getId).collect(Collectors.toSet());
            Set<Integer> businessIds = bmsUserReceCoupons.stream().map(BmsUserReceCoupon::getBusinessId).collect(Collectors.toSet());
            List<CountBussinessActivity> countBussinessActivities = countBussinessActivityService.getBaseDao().findByBusinessIdIn(businessIds);
            Map<Integer,CountBussinessActivity> countBussinessActivityMap = new HashMap<>();
            if(countBussinessActivities != null && countBussinessActivities.size() > 0){
                for(CountBussinessActivity countBussinessActivity : countBussinessActivities) {
                    countBussinessActivityMap.put(countBussinessActivity.getBusinessId(),countBussinessActivity);
                }
            }
            Map<Integer, Map<String,Double>> userPayMap = bmsUserReceCouponService.countOrderTotalReceive(userReceIds);
            if(userPayMap.size() > 0){
                List<CountBussinessActivity> cut = new ArrayList<>();
                for(Integer businessId : businessIds){
                    CountBussinessActivity countBussinessActivity = null;
                    if(countBussinessActivityMap.containsKey(businessId)){
                        countBussinessActivity = countBussinessActivityMap.get(businessId);
                    }else {
                        Optional<BmsBusiness> bmsBusinessOptional = bmsBusinessService.getBaseDao().findById(businessId);
                        if(bmsBusinessOptional.isPresent()) {
                            BmsBusiness business = bmsBusinessOptional.get();
                            countBussinessActivity = countBussinessActivityService.initCountBussinessActivity(countBussinessActivity,business);
                        }
                    }
                    if (userPayMap.containsKey(countBussinessActivity.getBusinessId())){
                        //如果有使用次数
                        if(countMap.containsKey(countBussinessActivity.getBusinessId())){
                            countBussinessActivity.setUseNum(countBussinessActivity.getUseNum() == null ? 0 + countMap.get(businessId) : countBussinessActivity.getUseNum() + countMap.get(businessId));
                        }
                        Map<String,Double> c = userPayMap.get(countBussinessActivity.getBusinessId());
                        countBussinessActivity.setTotalMoney(countBussinessActivity.getTotalMoney() == null ? 0d : ArithUtil.add(countBussinessActivity.getTotalMoney(),c.get("total")));
                        countBussinessActivity.setComMoney(countBussinessActivity.getComMoney() == null ? 0d : ArithUtil.add(countBussinessActivity.getComMoney(),c.get("platformAmount")));
                        countBussinessActivity.setSubMoney(countBussinessActivity.getSubMoney() == null ? 0d : ArithUtil.add(countBussinessActivity.getSubMoney(),c.get("discountConsum")));
                        Double perCom = ArithUtil.div(countBussinessActivity.getComMoney(),countBussinessActivity.getTotalMoney(),4);
                        countBussinessActivity.setPerCom(ArithUtil.mul(perCom,100) + "%");
                        cut.add(countBussinessActivity);
                    }
                }
                if(cut != null && cut.size() > 0){
                    countBussinessActivityService.getBaseDao().saveAll(cut);
                }
            }
        }
    }

    /**
     * @Description 查询这个时间段用户收到的所有券
     * @Author: cfx
     * @Date: 2019/10/1
     */
    public void countBusinessToSendStamps(Date startTime, Date nowTime) {
        Map<String,Object> condtionMap = new HashMap<>();
        condtionMap.put("newTime_GTTE",startTime);
        condtionMap.put("newTime_LTT",nowTime);
        List<BmsUserReceCoupon> bmsUserReceCoupons = bmsUserReceCouponService.getBaseDao().findAll(new SpecificationUtils(condtionMap));
        if(bmsUserReceCoupons != null && bmsUserReceCoupons.size() > 0){
            Set<Integer> businessIds = new HashSet<>();
            Map<Integer,Integer> countMap = new HashMap<>();
            for(BmsUserReceCoupon bmsUserReceCoupon : bmsUserReceCoupons){
                businessIds.add(bmsUserReceCoupon.getBusinessId());
                if(!countMap.containsKey(bmsUserReceCoupon.getBusinessId())){
                    countMap.put(bmsUserReceCoupon.getBusinessId(),0);
                }
                countMap.put(bmsUserReceCoupon.getBusinessId(),countMap.get(bmsUserReceCoupon.getBusinessId()) + 1);
            }
            if(businessIds.size() > 0){
                List<CountBussinessActivity> cut = new ArrayList<>();
                List<CountBussinessActivity> countBussinessActivities = countBussinessActivityService.getBaseDao().findByBusinessIdIn(businessIds);
                Map<Integer,CountBussinessActivity> countBussinessActivityMap = new HashMap<>();
                if(countBussinessActivities != null && countBussinessActivities.size() > 0){
                    for(CountBussinessActivity countBussinessActivity : countBussinessActivities){
                        countBussinessActivityMap.put(countBussinessActivity.getBusinessId(),countBussinessActivity);
                    }
                }
                for(Integer businessId : businessIds){
                    CountBussinessActivity countBussinessActivity = null;
                    if(countBussinessActivityMap.containsKey(businessId)){
                        countBussinessActivity = countBussinessActivityMap.get(businessId);
                        if(countMap.containsKey(businessId)){
                            countBussinessActivity.setNumber(countBussinessActivity.getNumber() == null ? (0 + countMap.get(businessId)) : (countBussinessActivity.getNumber() + countMap.get(businessId)));
                            cut.add(countBussinessActivity);
                        }
                    }else {
                        Optional<BmsBusiness> bmsBusinessOptional = bmsBusinessService.getBaseDao().findById(businessId);
                        if(bmsBusinessOptional.isPresent()) {
                            BmsBusiness business = bmsBusinessOptional.get();
                            countBussinessActivity = countBussinessActivityService.initCountBussinessActivity(countBussinessActivity,business);
                            countBussinessActivity.setNumber(countBussinessActivity.getNumber() == null ? (0 + countMap.get(businessId)) : (countBussinessActivity.getNumber() + countMap.get(businessId)));
                            cut.add(countBussinessActivity);
                        }
                    }
                }
                if(cut != null && cut.size() > 0) {
                    countBussinessActivityService.getBaseDao().saveAll(cut);
                }
            }
        }


    }
}
